/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package matematikapirma.math;

import java.util.List;
import matematikapirma.sys.MPoint;
import java.util.ArrayList;
import matematikapirma.CurveAlgorithm;
import matematikapirma.Point;

/**
 *
 * @author Tadas
 */
public class C1SplineCurveAlgorithm implements CurveAlgorithm {

    public List<Point> calculatePoints(List<Point> initialPoints, boolean open, int steps, int start, int end) {
        if (initialPoints.size() < 3) {
            return new ArrayList<Point>();
        }

        ArrayList<Point> rpoints = new ArrayList<Point>();

        rpoints.clear();

        ArrayList<Point> points = new ArrayList<Point>();
        ArrayList<Point> tempPoints = new ArrayList<Point>();
        ArrayList<Point> tp = new ArrayList<Point>();


        double x, y;
        points.addAll(initialPoints);

        if (!open) {
            points.add(0, initialPoints.get(initialPoints.size() - 1));
            points.add(initialPoints.get(0));
        }

        for (int i = 0; i + 2 < points.size(); i++) {
            x = (points.get(i).getX() + points.get(i + 1).getX()) * 0.5;
            y = (points.get(i).getY() + points.get(i + 1).getY()) * 0.5;

            Point t1 = new MPoint(x, y);

            x = (points.get(i + 1).getX() + points.get(i + 2).getX()) * 0.5;
            y = (points.get(i + 1).getY() + points.get(i + 2).getY()) * 0.5;

            Point t2 = new MPoint(x, y);

            tempPoints.clear();

            tempPoints.add(t1);
            tempPoints.add(points.get(i + 1));
            tempPoints.add(t2);

            for (int j = 0; j < steps; j++) {
                for (int k = 0; k + 2 < tempPoints.size();) {
                    x = (tempPoints.get(k).getX() + tempPoints.get(k + 1).getX()) * 0.5;
                    y = (tempPoints.get(k).getY() + tempPoints.get(k + 1).getY()) * 0.5;

                    Point p1 = new MPoint(x, y);

                    x = (tempPoints.get(k + 1).getX()
                            + tempPoints.get(k + 2).getX()) * 0.5;
                    y = (tempPoints.get(k + 1).getY()
                            + tempPoints.get(k + 2).getY()) * 0.5;

                    Point p3 = new MPoint(x, y);


                    x = (p3.getX() + p1.getX()) * 0.5;
                    y = (p3.getY() + p1.getY()) * 0.5;

                    Point p2 = new MPoint(x, y);
                    tp.add(tempPoints.get(k));
                    tp.add(p1);
                    tp.add(p2);
                    tp.add(p3);

                    if (k + 3 == tempPoints.size()) {
                        tp.add(tempPoints.get(k + 2));
                    }


                    k = k + 2;

                }
                tempPoints.clear();
                tempPoints.addAll(tp);
                tp.clear();
            }
            rpoints.addAll(tempPoints);
        }

        if (open) {
            rpoints.add(0, initialPoints.get(0));

            rpoints.add(initialPoints.get(initialPoints.size() - 1));
        }
        return rpoints;
    }

    @Override
    public String toString() {
        return "C1 Spline";
    }
}
